home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
PROGENV
/
ClassTree.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-02
|
14KB
|
616 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "ClassTree.h"
#include "ET++.h"
#include "Zoomer.h"
#include "OrdColl.h"
#include "Set.h"
#include "AccessMem.h"
#include "ClassManager.h"
#include "String.h"
#include "ClassItem.h"
#include "ProgEnv.h"
#include "EtPeCmdNo.h"
#include "EtPeManager.h"
static RGBColor *c1;
static OrdCollection *treeViews= 0;
ONEXIT(PeClassTree)
{
SafeDelete(c1);
}
//---- PeClassTreeView ----------------------------------------------------------
NewMetaImpl0(PeClassTreeView, TreeView);
PeClassTreeView::PeClassTreeView(EvtHandler *eh, Class *root)
: TreeView(eh, eTLLeftRight, eTCDiagonal2)
{
if (treeViews == 0)
treeViews= new OrdCollection;
treeViews->Add(this);
gClassManager->SetupSubclasses();
classes= new OrdCollection(200);
InstallTree(root);
show= ePeCTShowAll;
references= new OrdCollection;
}
PeClassTreeView::~PeClassTreeView()
{
SafeDelete(classes);
treeViews->RemovePtr(this);
if (treeViews->Size() == 0)
SafeDelete(treeViews);
if (references) {
references->FreeAll();
SafeDelete(references);
}
}
VObject *PeClassTreeView::NodeAsVObject(Object *op)
{
Class *cl= Guard(op, Class);
VObject *vop= new PeClassItem(cIdClassItem, cl);
classes->Add(vop);
return vop;
}
Iterator *PeClassTreeView::MakeChildrenIter(Object *op)
{
return Guard(op, Class)->SubclassIterator();
}
Command *PeClassTreeView::GetNodeSelector(TreeNode *tn, int cl)
{
VObject *vop= tn->At(0)->FindItem(cIdClassItem);
if (vop && vop->IsKindOf(PeClassItem) && vop->TestFlag(eClItemCollapsed))
return new PeNameTreeNodeSelector(tn, cl);
return TreeView::GetNodeSelector(tn, cl);
}
void PeClassTreeView::ShowClass(Class *cl)
{
PeClassItem *ci= FindClassItem(cl);
if (ci) {
RevealRect(ci->ContentRect().Expand(100), Point(0, 100));
SetSelection((VObject*)ci->GetNextHandler());
UpdateEvent();
}
}
void PeClassTreeView::SetSelection(VObject *vop)
{
TreeView::SetSelection(vop);
SynchSelection();
}
void PeClassTreeView::SynchSelection()
{
VObject *sel= GetSelection();
PeClassItem *cl= 0, *cl2= 0;
if (sel)
cl= Guard(sel->FindItem(cIdClassItem), PeClassItem);
if (treeViews && cl) {
Iter next(treeViews);
PeClassTreeView *tvp;
while (tvp= (PeClassTreeView*)next()) {
VObject *sel2= tvp->GetSelection();
if (sel2)
cl2= Guard(sel2->FindItem(cIdClassItem), PeClassItem);
if (cl2->GetClass() != cl->GetClass())
tvp->ShowClass(cl->GetClass());
}
}
}
Class *PeClassTreeView::GetRootClass()
{
TreeNode *tn= GetTree();
PeClassItem *cl= Guard(GetTree()->FindItem(cIdClassItem), PeClassItem);
return cl->GetClass();
}
void PeClassTreeView::ShowAllClasses()
{
show= ePeCTShowAll;
classes->ForEach(PeClassItem,ResetFlag)(eClItemCollapsed);
CalcLayout();
}
void PeClassTreeView::ShowOnlyAbstractClasses()
{
Iter next(classes);
PeClassItem *cl;
show= ePeCTShowAbstract;
classes->ForEach(PeClassItem,ResetFlag)(eClItemCollapsed);
while (cl= (PeClassItem*)next())
if (!cl->GetClass()->IsAbstract())
cl->SetFlag(eClItemCollapsed);
CalcLayout();
}
void PeClassTreeView::ShowOnlyApplicationClasses()
{
static char *etsrc= 0;
Iter next(classes);
PeClassItem *cl;
char buf[1024];
if (etsrc == 0)
etsrc= strprintf("%s/src", gEtDir);
int len= strlen(etsrc);
show= ePeCTShowApp;
classes->ForEach(PeClassItem,ResetFlag)(eClItemCollapsed);
while (cl= (PeClassItem*)next()) {
Class *cp= cl->GetClass();
if (gEtPeManager->FileOfClass(cp, buf, TRUE)) {
if (strncmp(etsrc, buf, len) == 0)
cl->SetFlag(eClItemCollapsed);
}
}
CalcLayout();
}
PeCTreeShow PeClassTreeView::Shows()
{
return show;
}
void PeClassTreeView::DoSetupMenu(Menu *menu)
{
TreeView::DoSetupMenu(menu);
VObject *sel= GetSelection();
if (sel) {
TreeNode *tn= FindTreeNode(sel);
char *current;
if (tn->Collapsed())
current= "Expand";
else
current= "Collapse";
menu->ReplaceItem(cDOCOLLAPSE, current);
}
}
Command *PeClassTreeView::DoMenuCommand(int cmd)
{
VObject *sel= GetSelection();
PeClassItem *cl= 0;
if (sel)
cl= Guard(selection->FindItem(cIdClassItem), PeClassItem);
switch (cmd) {
case cMEMBERS:
ShowMembers(cl);
break;
case cCLIENTS:
ShowAllClients(cl);
break;
case cSOURCE:
Control(cPeHierBrowser, cPeShowBrowser, cl->GetClass());
break;
case cSPAWN:
Control(cPeHierBrowser, cPeSpawnHier, gClassManager->Find("Object"));
break;
case cDOCOLLAPSE:
Collapse(FindTreeNode(selection));
break;
case cPROMOTE:
Control(cPeHierBrowser, cPeSpawnHier, cl->GetClass());
break;
case cTREEVIEW:
SetLayout(eTLLeftRight);
break;
case cOUTLINEVIEW:
SetLayout(eTLIndented);
break;
default:
return TreeView::DoMenuCommand(cmd);
}
return gNoChanges;
}
void PeClassTreeView::Draw(Rectangle r)
{
if (references) {
references->ForEach(PeClassReference,Draw)(r);
}
TreeView::Draw(r);
}
void PeClassTreeView::AddReference(PeClassReference *cr)
{
references->Add(cr);
InvalidateRect(cr->BBox());
}
void PeClassTreeView::RemoveAllReferences()
{
references->FreeAll();
references->Empty(0);
ForceRedraw();
}
void PeClassTreeView::OpenTreeNode(TreeNode *tn, bool)
{
if (references->Size() == 0)
return;
Iter next(references);
VObject *ci= tn->At(0)->FindItem(cIdClassItem);
if (ci && ci->IsKindOf(PeClassItem)) {
PeClassReference *cr;
while (cr= (PeClassReference*)next()) {
if (cr->Includes((PeClassItem*)ci))
InvalidateRect(cr->BBox());
}
}
}
//---- PeCollectClassMembers -----------------------------------------------------
class PeCollectClassMembers : public AccessMembers {
Collection *cp;
public:
PeCollectClassMembers()
{ cp= new OrdCollection; }
~PeCollectClassMembers()
{ SafeDelete(cp); }
void Member(char *, int, int, int, Class *cl, bool, bool)
{ cp->Add(cl); }
Collection *GetCollection()
{ return cp; }
};
void PeClassTreeView::ShowMembers(PeClassItem *ci)
{
PeCollectClassMembers clm;
Class *cp= ci->GetClass(), *clp;
Collection *colItems= new OrdCollection;
cp->EnumerateMyMembers(&clm);
Iter next(clm.GetCollection());
while (clp= (Class *)next())
colItems->Add(FindClassItem(clp));
AddReference (new PeMemberReference(ci, colItems));
}
//---- PeCollectClients ----------------------------------------------------------
class PeCollectClients : public AccessMembers {
Collection *colp;
Class *clp, *current;
public:
PeCollectClients(Class *c)
{ colp= new Set; clp= c; }
~PeCollectClients()
{ SafeDelete(colp); }
void SetCurrent(Class *cp)
{ current= cp; }
void Member(char *, int, int, int, Class *cl, bool, bool)
{ if (clp == cl) colp->Add(current); }
Collection *GetCollection()
{ return colp; }
};
void PeClassTreeView::ShowAllClients(PeClassItem *ci)
{
Class *cp;
PeCollectClients clm(ci->GetClass());
Iter next(gClassManager->Iterator());
while (cp= (Class*)next()) {
clm.SetCurrent(cp);
cp->EnumerateMyMembers(&clm);
}
Collection *colItems= new OrdCollection;
Iter next2(clm.GetCollection());
while (cp= (Class *)next2())
colItems->Add(FindClassItem(cp));
AddReference (new PeClassReference(ci, colItems, ePatBlack));
}
PeClassItem *PeClassTreeView::FindClassItem(Class *cp)
{
PeClassItem dummy(0,cp);
return (PeClassItem*)classes->Find(&dummy);
}
TreeNode *PeClassTreeView::FindTreeNode(VObject *vop)
{
return (TreeNode*)vop->FindNextHandlerOfClass(Meta(TreeNode));
}
//---- NameTreeNodeSelector -------------------------------------------------------------
PeNameTreeNodeSelector::PeNameTreeNodeSelector(TreeNode *tn, int cl)
{
item= tn;
lastinside= FALSE;
clicks= cl;
fp= gFixedFont->WithFace(eFaceBold);
VObject *vop= tn->At(0)->FindItem(cIdClassItem);
if (vop && vop->IsKindOf(PeClassItem))
name= ((PeClassItem*)vop)->ClassName();
p= vop->ContentRect().NE();
}
void PeNameTreeNodeSelector::TrackFeedback(Point, Point, bool)
{
if (item && (lastinside != inside)) {
GrShowString(fp, ePatXor, p, (byte*) name);
item->At(0)->Outline(0);
lastinside= inside;
}
}
Command *PeNameTreeNodeSelector::TrackMouse(TrackPhase atp, Point, Point, Point np)
{
VObject *image= item->At(0);
inside= image->ContainsPoint(np);
if (atp == eTrackRelease) {
if (item && lastinside) {
GrShowString(fp, ePatXor, p, (byte*) name);
image->Outline(0);
item->GetTreeView()->SetSelection(image);
return item->GetTreeView()->NodeSelected(item->At(0), clicks);
}
}
return this;
}
//---- PeClassReference --------------------------------------------------------------------------
PeClassReference::PeClassReference(PeClassItem *c, Collection *refs, GrPattern p, int w)
{
cl= c;
nodes= refs;
width= w;
pat= p;
}
PeClassReference::~PeClassReference()
{
SafeDelete(nodes);
}
bool PeClassReference::Includes(PeClassItem *ci)
{
return nodes->ContainsPtr(ci) || (ci == cl);
}
void PeClassReference::Draw(Rectangle)
{
PeClassItem *clp;
Iter next(nodes);
if (!cl->IsOpen())
return;
GrSetPenNormal();
GrStrokeRect(cl->contentRect.Expand(1));
while (clp= (PeClassItem*)next()) {
if (clp->IsOpen()) {
GrSetPenNormal();
GrStrokeRect(clp->ContentRect().Expand(1));
DrawConnection(cl, clp);
}
}
}
void PeClassReference::DrawConnection(PeClassItem *from, PeClassItem *to)
{
GrMoveto(from->contentRect.Center());
GrSetPenSize(1);
SetWidthAndPattern(from, to);
if (from == to)
CircularReference(from);
else {
GrMoveto(from->contentRect.Center());
GrLineto(to->contentRect.Center());
}
}
static RGBColor *c2;
void PeClassReference::SetWidthAndPattern(PeClassItem*, PeClassItem*)
{
if (c2 == 0)
c2= new_RGBColor(0, 256, 0);
GrSetPenSize(width);
GrSetPenInk(c2);
}
void PeClassReference::CircularReference(PeClassItem *ci)
{
int d= ci->ContentRect().Height();
Rectangle rr(ci->ContentRect().NE()-Point(d/2), Point(d));
GrStrokeOval(rr);
}
Rectangle PeClassReference::BBox()
{
Rectangle r;
VObject *clp;
Iter next(nodes);
r= cl->ContentRect().Expand(20);
while ((clp= (VObject *)next()))
r.Merge(clp->ContentRect().Expand(4));
return r;
}
//---- PeMemberReference ---------------------------------------------------------
PeMemberReference::PeMemberReference(PeClassItem *cl, Collection *n) :
PeClassReference(cl, n)
{
}
void PeMemberReference::SetWidthAndPattern(PeClassItem*, PeClassItem*)
{
if (c1 == 0)
c1= new RGBColor(256, 0, 0);
GrSetPenInk(c1);
}
//---- PeHierarchyBrowser --------------------------------------------------------
NewMetaImpl(PeHierarchyBrowser,EtPeTool, (TP(ct)));
PeHierarchyBrowser *PeHierarchyBrowser::hierBrowser;
PeHierarchyBrowser::PeHierarchyBrowser(Manager *m, Class *root)
: EtPeTool(m, "Class Hierarchy")
{
ct= new PeClassTreeView(this, root);
}
VObject *PeHierarchyBrowser::DoMakeContent()
{
hierZoomer= new Zoomer(ct);
hierZoomer->SetBgInk(gInkNone);
SetFirstHandler(ct);
return new VExpander(gPoint5,
hierZoomer,
0
);
}
Point PeHierarchyBrowser::GetInitialWindowSize()
{
return Point(600,600);
}
PeHierarchyBrowser::~PeHierarchyBrowser()
{
SafeDelete(ct);
}
MenuBar *PeHierarchyBrowser::DoMakeMenuBar()
{
MenuBar *mb= EtPeTool::DoMakeMenuBar();
Menu *m= Zoomer::MakeMenu(cVIEWMENU);
m->InsertItemsBefore(cZOOMOUT,
"Tree", cTREEVIEW,
"Outline", cOUTLINEVIEW,
"-",
"All Classes", cALLCLASSES,
"Abstract Classes", cONLYABSTRACT,
"Application Classes", cONLYAPPL,
"-",
0);
mb->AddMenu(m);
m= new Menu("Classes");
m->AppendItems(
"Members", cMEMBERS,
"Clients", cCLIENTS,
"Show Source", cSOURCE,
"-",
"Clear Lines", cCLEARREFS,
"-",
"Collapse", cDOCOLLAPSE,
"Promote", cPROMOTE,
0);
mb->AddMenu(m);
return mb;
}
void PeHierarchyBrowser::DoSetupMenu(Menu *mp)
{
EtPeTool::DoSetupMenu(mp);
Clipper *vf= hierZoomer->GetClipper();
if (vf->GetZoom() < 1024)
mp->EnableItem(cZOOMIN);
if (vf->GetZoom() > 0.01)
mp->EnableItem(cZOOMOUT);
mp->EnableItems(cZOOMRESET, cTREEVIEW, cOUTLINEVIEW, 0);
mp->CheckItem(cOUTLINEVIEW, ct->GetLayout() == eTLIndented);
mp->CheckItem(cTREEVIEW, ct->GetLayout() == eTLLeftRight);
mp->CheckItem(cALLCLASSES, ct->Shows() == ePeCTShowAll);
mp->CheckItem(cONLYABSTRACT, ct->Shows() == ePeCTShowAbstract);
mp->CheckItem(cONLYAPPL, ct->Shows() == ePeCTShowApp);
mp->EnableItems(cMEMBERS, cCLIENTS, cSOURCE, cDOCOLLAPSE, cCLEARREFS,
cALLCLASSES, cONLYABSTRACT, cONLYAPPL, cPROMOTE, 0);
}
Command *PeHierarchyBrowser::DoMenuCommand(int cmd)
{
Clipper *vf= hierZoomer->GetClipper();
switch (cmd) {
case cZOOMOUT:
vf->SetZoom(vf->GetZoom()/1.2);
break;
case cZOOMIN:
vf->SetZoom(vf->GetZoom()*1.2);
break;
case cZOOMRESET:
vf->SetZoom(1.0);
break;
case cONLYABSTRACT:
ct->ShowOnlyAbstractClasses();
break;
case cONLYAPPL:
ct->ShowOnlyApplicationClasses();
break;
case cALLCLASSES:
ct->ShowAllClasses();
break;
case cCLEARREFS:
ct->RemoveAllReferences();
break;
default:
return EtPeTool::DoMenuCommand(cmd);
}
return gNoChanges;
}
void PeHierarchyBrowser::ShowClass(Class *cp)
{
ct->ShowClass(cp);
}
void PeHierarchyBrowser::Spawn(Manager *m, Class *root)
{
PeHierarchyBrowser *hb= new PeHierarchyBrowser(m, root);
hb->SetOnDismiss(eMgrClose);
hb->Show();
}
void PeHierarchyBrowser::ShowClass(Manager *m, Class *selection)
{
if (hierBrowser == 0)
hierBrowser= new PeHierarchyBrowser(m, gClassManager->Find("Object"));
hierBrowser->Show();
hierBrowser->ShowClass(selection);
}